Moving, Scaling, Rotating, and Skewing Shapes
The mapping property of transform objects allows you to perform sophisticated transformations to your shape's geometries. By altering the values of a transform's mapping, you can move, scale, rotate, skew and create perspective effects on any shapes the transform applies to. However, determining the specific changes to the mapping matrix needed to achieve a desired transformational effect can involve complex calculations. As a convenience, QuickDraw GX provides several functions that perform the calculations necessary to achieve common transformations, without you having to know how the mapping matrix is altered.The transformational functions that QuickDraw GX provides allow you to position, rotate, scale, and skew shapes. QuickDraw GX provides two kinds of such functions, one kind that operates on transform mappings, which is of the form
GXActionTransform
, and one kind that normally operates on shape geometries, which is of the formGXActionShape
. If you use a function that operates on a transform's mapping, the mapping is changed and all shapes that refer to the transform are affected. If you use a function that normally operates on a shape geometry, there are two possible results:
If you move a shape to an absolute location, the location applies to a specific anchor point in the shape's geometry and all other points in the geometry move in relation to this point. The point used depends on the kind of shape:
- If the shape's
gxMapTransformShape
attribute is cleared, the shape's geometry is changed, as expected. Its transform mapping is unaffected.- If the shape's
gxMapTransformShape
attribute is set, the function works exactly like aGXActionTransform
function, changing the transform mapping instead of the shape geometry. An additional side effect is that, if the shape's transform object is shared with other shapes, QuickDraw GX creates a copy of the transform and modifies the copy, to avoid affecting the other shapes.
However, remember that if the shape's
- For points, lines, and curves, the anchor point is the first point in the shape's geometry.
- For rectangles, polygons, paths, and bitmaps, the anchor point is the top-left corner of the bounding rectangle.
- For text, glyph, and layout shapes, the anchor point is the origin of the first glyph.
- Other shapes (empty shapes, full shapes, and pictures) cannot be moved.
gxMapTransformShape
attribute is set, calling a function that moves the shape has no effect on the geometry; it modifies the transform mapping instead. In that case, moving the shape to an absolute location means only that its transform mapping adds that location to whatever location the geometry already specifies.Modifying the Transform Mapping
One way to transform a shape is by altering its transform object's mapping property. This section shows several examples of that kind of transformation.For example, you can move a shape to a relative or absolute location by modifying its transform. The
GXMoveTransform
function modifies the transform's mapping to
move a shape a specified distance from its current location in local coordinates. TheGXMoveTransformTo
function modifies the transform's mapping to move a shape
to an absolute location in local coordinate space.The following example causes all shapes associated with the myTransform transform object to move to the upper-left corner of the bounding rectangle,
bounds
, of the rectangleaRectangle
:
gxRectangle aRectangle, bounds; . . /* initialize the rectangle (not shown) */ . GXGetShapeBounds(aRectangle, 0, &bounds); GXMoveTransformTo(myTransform, bounds.left, bounds.top);You can also modify a transform's mapping to rotate, scale, or skew a shape around a specified point. Listing 6-3 rotates a shape's transform mapping 90 degrees, and scales and skews the mapping. The shape's center is used as the point around which to rotate, scale, and skew the transform.Listing 6-3 Modifying a shape's transform with transform-mapping calls only
Fixed hScale, vScale, xSkew, ySkew; gxPoint center; gxShape aShape; gxTransform myTransform; . . /* initialize the shape and the rotate/scale/skew parameters */ . /* find the shape's center */ GXGetShapeCenter(aShape, 0, ¢er); /* get the transform, rotate it around shape's center */ myTransform = GXGetShapeTransform(aShape); GXRotateTransform(myTransform, ff(90), center.x, center.y); /* scale and skew the shape */ GXScaleTransform(myTransform, hScale, vScale, center.x, center.y); GXSkewTransform(myTransform, xSkew, ySkew, center.x, center.y);Listing 6-4 performs the same actions as Listing 6-3: rotating, scaling, and skewing a shape's transform mapping. Like Listing 6-3, this code also affects only the transform mapping associated with the shape. This is despite the fact that it makes some calls (GXScaleShape
andGXSkewShape
) that would normally affect the shape's
geometry. Because the shape's gxMapTransformShape attribute is set before the geometry-altering calls are made, those functions are forced to affect the transform mapping instead of the shape's geometry.Listing 6-4 Modifying a shape's transform with transform-mapping and shape-geometry calls
Fixed hScale, vScale, xSkew, ySkew; gxPoint center; gxShape aShape; gxTransform myTransform; . . /* initialize the shape and the rotate/scale/skew parameters */ . /* find the shape's center */ GXGetShapeCenter(aShape, 0, ¢er); /* get the transform, rotate it around shape's center */ myTransform = GXGetShapeTransform(aShape); GXRotateTransform(myTransform, ff(90), center.x, center.y); /* set the gxMapTransformShape attribute */ GXSetShapeAttributes(aShape, GXGetShapeAttributes(aShape) | gxMapTransformShape); /* scale and skew the shape (but it affects mapping instead) */ GXScaleShape(aShape, hScale, vScale, center.x, center.y); GXSkewShape(aShape, xSkew, ySkew, center.x, center.y);You can also perform these transformations, as well as perspective-modifying operations, by directly manipulating the matrix elements of a transform's mapping. You can use the functionsGXGetTransformMapping
orGXGetShapeMapping
to obtain the mapping matrix, then modify the matrix as desired and reassign it to the transform withGXSetTransformMapping
orGXSetShapeMapping
. You can also create your own mapping matrix, and then multiply it (concatenate it) with the existing mapping of a transform object, using the functionsGXMapTransform
(orGXMapShape
, if the shape'sgxMapTransformShape
attribute is set). For more information about matrix manipulation, see the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.The
GXGetTransformMapping
function is described on page 6-54; theGXSetTransformMapping
function is described on page 6-55.
TheGXGetShapeMapping
function is described on page 6-56; theGXSetShapeMapping
function is described on page 6-57.The
GXMapTransform
function is described on page 6-64; theGXMapShape
function
is described on page 6-72.The
GXMoveTransform
function is described on page 6-58. TheGXMoveTransformTo
function is described on page 6-59. TheGXScaleTransform
function is described on page 6-60. TheGXRotateTransform
function is described on page 6-62. TheGXSkewTransform
function is described on page 6-63.Modifying Shape Geometry
A second way to transform a shape is by altering its geometry property. This section shows several examples of that kind of transformation.You can move a shape to a relative or absolute location by modifying the shape's geometry instead of its transform mapping. The
GXMoveShape
function modifies the geometry to move a shape a specified distance from its current location in local coordinates. TheGXMoveShapeTo
function modifies the geometry to move a shape to an absolute location in local coordinate space. In either case, the geometry is altered only if the shape's gxMapTransformShape attribute is cleared; otherwise, the functions work just likeGXMoveTransform
andGXMoveTransformTo
, and alter the mapping of the transform object attached to the shape.The following example causes the shape myShape to move to the upper-left corner of the bounding rectangle,
bounds
, of the rectangleaRectangle
:
gxRectangle aRectangle, bounds; . . /* initialize the rectangle (not shown) */ . GXGetShapeBounds(aRectangle, 0, &bounds); GXMoveShapeTo(myShape, bounds.left, bounds.top);Listing 6-5 performs the same actions as Listing 6-3 and Listing 6-4: rotating, scaling, and skewing a shape. However, unlike either previous listing, this code alters the geometry of the shape itself. To ensure that the operations do not affect the shape's transform mapping, the code clears the shape's gxMapTransformShape attribute before making the geometry-altering calls.Listing 6-5 Modifying a shape's geometry with shape-geometry calls
Fixed hScale, vScale, xSkew, ySkew; gxPoint center; gxShape aShape; . . /* initialize the shape and the rotate/scale/skew parameters */ . /* find the shape's center */ GXGetShapeCenter(aShape, 0, ¢er); /* clear the gxMapTransformShape attribute */ GXSetShapeAttributes(aShape, gxNoAttributes); /* rotate shape around its center (affects geometry this time ) */ GXRotateShape(myShape, ff(90), center.x, center.y); /* scale and skew the shape (affects geometry this time ) */ GXScaleShape(aShape, hScale, vScale, center.x, center.y); GXSkewShape(aShape, xSkew, ySkew, center.x, center.y);You can also perform these operations, as well as perspective-modifying operations, by applying a mapping directly to a shape's geometry. You can create your own mapping matrix, and then apply it to a shape object using the
- Note
- Rotation of a shape's geometry can change the shape's type. For example, a rectangle may turn into a polygon when rotated. For more information, see the geometric shapes chapter of Inside Macintosh: QuickDraw GX Graphics.
![]()
GXMapShape
function if the shape'sgxMapTransformShape
attribute is cleared; if the attribute is set, this function affects the shape's transform mapping instead. For more information about matrix manipulation, see the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.The
GXMapShape
function is described on page 6-72.The
GXMoveShape
function is described on page 6-66. TheGXMoveShapeTo
function is described on page 6-67. TheGXScaleShape
function is described on page 6-68. TheGXRotateShape
function is described on page 6-70. TheGXSkewShape
function is described on page 6-71.